#include "TreeView.hpp"
#include "MainView.hpp"
#include "M3gView.hpp"
#include "Scene.hpp"
#include "FL/Fl_Tree.H"
#include "FL/Fl_Button.H"
#include "m3g/m3g.hpp"
#include "constants.hpp"
#include <iostream>
#include <typeinfo>
using namespace m3g;
using namespace m3g_viewer;
using namespace std;

static void callback_select_tree_item (Fl_Widget* w, void* v);


TreeView:: TreeView (MainView* view, int x, int y) : Fl_Window(TREE_VIEW_WIDTH,
                                                               TREE_VIEW_HEIGHT,
                                                               "ツリー・ビュー"),
                                                     main_view(view)
{
    Scene* scene = main_view->get_m3g_view()->get_scene();
    World* wld   = scene->get_world();

    Fl_Tree* tree = new Fl_Tree (OBJECT_TREE_X,
                                 OBJECT_TREE_Y,
                                 OBJECT_TREE_REAL_WIDTH,
                                 OBJECT_TREE_REAL_HEIGHT);
    tree->begin ();
    register_tree_item (tree, wld, "");
    tree->end ();
    tree->callback (callback_select_tree_item, main_view);

    end ();

    resizable (tree);
}


TreeView:: ~TreeView ()
{

}

void TreeView:: register_tree_item (Fl_Tree* tree, m3g::Group* grp, string hierarchy)
{
    if (!grp) {
        return;
    }

    //hierarchy += grp->name();
    hierarchy += typeid(*grp).name();
    Fl_Tree_Item* item;
    item = tree->add (hierarchy.c_str());
    item->user_data (grp);
    hierarchy += "/";
    for (int i = 0; i < grp->getChildCount(); i++) {
        Node*  n = grp->getChild(i);
        Group* g = dynamic_cast<Group*>(n);
        if (g != NULL) {
            register_tree_item (tree, g, hierarchy);
        } else {
            string s = hierarchy + typeid(n).name();
            Fl_Tree_Item* item;
            item = tree->add (s.c_str());
            item->user_data (n);
        }
    }
}


void callback_select_tree_item (Fl_Widget* w, void* v)
{
    Fl_Tree*      tree  = (Fl_Tree*)w;
    Fl_Tree_Item* item  = (Fl_Tree_Item*)tree->callback_item();
    MainView*     main  = (MainView*)v;

    switch (tree->callback_reason()) {
    case FL_TREE_REASON_SELECTED:
        main->show_object_view (item->user_data());
        break;
    default:
        // nothing to do
        break;
    }
}

void cb_button (Fl_Widget* w, void* v)
{
    cout << "Clicked\n";
}

